package player;

/**
 * Implementation of the TV effect.
 * One of four possible TV logos will be shown with four
 * possible positions: upper/lower left corner and upper/lower right corner.
 */

import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.media.Buffer;
import javax.media.Effect;
import javax.media.Format;
import javax.media.format.RGBFormat;

public class MyEffect implements Effect {
	private Format inputFormat;
	private Format outputFormat;
	private Format[] inputFormats;
	private Format[] outputFormats;

	int displayCorner = 1;
	int tvStation = 1;
	boolean effectActive = false;
	
	BufferedImage bufferedImage;
	int[] pixels;
	
	int wImage;
	int hImage;
	int wVideo;
	int hVideo;

	//constructor for effect with input- and outputformats
	public MyEffect() {
		inputFormats = new Format[] { new RGBFormat(null,Format.NOT_SPECIFIED,Format.intArray,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED) };
		outputFormats = new Format[] { new RGBFormat(null,Format.NOT_SPECIFIED,Format.intArray,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED,Format.NOT_SPECIFIED) };
	}

	/*
	 * @author Michael Kascha 0548800
	 * The Video Effect, data will be written to out Buffer	
	 */
	public synchronized int process(Buffer in, Buffer out) {
		out.copy(in, true);
		
		RGBFormat inFormat = (RGBFormat)in.getFormat();
		Dimension inSize = inFormat.getSize();
		wVideo = (int) inSize.getWidth();
		hVideo = (int) inSize.getHeight();

		if (in.getData() instanceof int[]) {
			int[] data = (int[]) out.getData();
			
			int currentImagePixel = 0;
			
			//apply effect only when time window is correct (set in Main.fx)
			if(effectActive) {
				// upper left corner
				if (displayCorner == 1) {
					for(int y=0; y<data.length; y++) {
						if ((y%wVideo) < wImage && hImage*wVideo > y && currentImagePixel < pixels.length) {
							// Treshhold value used to make the background and very bright pixels transparent
							if ((new Color(pixels[currentImagePixel]).getRed()) < 230) {
								data[y]= pixels[currentImagePixel];
							}
							else {
								data[y]=data[y];
							}
							currentImagePixel += 1;
						}
						else {
							data[y]=data[y];
						}
					}
				}
				
				// upper right corner
				else if (displayCorner == 2) {
					for(int y=0; y<data.length; y++) {
						if ((y%wVideo) > wVideo-wImage-1 && hImage*wVideo > y && currentImagePixel < pixels.length) {
							// Treshhold value used to make the background and very bright pixels transparent
							if ((new Color(pixels[currentImagePixel]).getRed()) < 230) {
								data[y]= pixels[currentImagePixel];
							}
							else {
								data[y]=data[y];
							}
							currentImagePixel += 1;
						}
						else {
							data[y]=data[y];
						}
					}
				}
				
				// lower left corner
				else if (displayCorner == 3) {
					for(int y=0; y<data.length; y++) {
						if ((y%wVideo) < wImage && (hVideo*wVideo)-(hImage*wVideo) < y && currentImagePixel < pixels.length) {
							// Treshhold value used to make the background and very bright pixels transparent
							if ((new Color(pixels[currentImagePixel]).getRed()) < 230) {
								data[y]= pixels[currentImagePixel];
							}
							else {
								data[y]=data[y];
							}
							currentImagePixel += 1;
						}
						else {
							data[y]=data[y];
						}
					}
				}
				
				// lower right corner
				else {
					for(int y=0; y<data.length; y++) {
						if ((y%wVideo) > wVideo-wImage-1 && (hVideo*wVideo)-(hImage*wVideo) < y && currentImagePixel < pixels.length) {
							// Treshhold value used to make the background and very bright pixels transparent
							if ((new Color(pixels[currentImagePixel]).getRed()) < 230) {
								data[y]= pixels[currentImagePixel];
							}
							else {
								data[y]=data[y];
							}
							currentImagePixel += 1;
						}
						else {
							data[y]=data[y];
						}
					}
				}
			}
			else {
			}
		}
		out.setFormat(outputFormat);
		return BUFFER_PROCESSED_OK;
	}
	
	//returns supported inputformats
	public Format[] getSupportedInputFormats() {
		return this.inputFormats;
	}

	//returns supported outputformats
	public Format[] getSupportedOutputFormats(Format f) {
		return new Format[] { this.outputFormats[0].intersects(f) };
	}
	
	//set inputformat
	public Format setInputFormat(Format input) {
		inputFormat = input;
		return input;
	}

	//set outputformat
	public Format setOutputFormat(Format output) {
		outputFormat = output;
		return output;
	}

	//returns name of the effect
	public String getName() {
		return "TVStation Effect";
	}
	
	//will read in the tv logos
	public void open() {
		if (tvStation == 1) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("DasErste.jpg"));
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
		if (tvStation == 2) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("RTL.jpg"));
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
		if (tvStation == 3) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("ATV.jpg"));
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
		if (tvStation == 4) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("SAT1.jpg"));
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
	        wImage = bufferedImage.getWidth();
	        hImage = bufferedImage.getHeight();
	        int[] size = new int[wImage*hImage];
			pixels = bufferedImage.getRGB(0, 0, wImage, hImage, size, 0,wImage);
	}
	
	public void close() {
	}
	
	public void reset() {
		close();
		open();
	}

	public Object getControl(String controlType) {
		return null;
	}

	public Object[] getControls() {	
		return null;
	}
	
	/*
	 * @author Michael Kascha 0548800
	 * setter for the javaFX buttons, so they can change the corner in which the tv logo will be displayed
	 * 1 = upperleft, 2=upperright, 3=lowerleft, 4=lowerright
	 */
	public void setDisplayCorner(int cornerNumber) {
		displayCorner = cornerNumber;
	}
	
	/*
	 * @author Evelyn Koller 0300033
	 * setter for effect use
	 */
	public void setEffect(boolean value) {
		effectActive = value;
	}
	
	/*
	 * @author Michael Kascha 0548800
	 * setter for the javaFX buttons, so they can change the tv station logo
	 * 1=ARD, 2=RTL, 3=ATV, 4=Sat1	
	 */
	public void setTVStation(int stationNumber) {
		if (stationNumber == 1) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("DasErste.jpg"));
				tvStation = 1;
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
		if (stationNumber == 2) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("RTL.jpg"));
				tvStation = 2;
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
		if (stationNumber == 3) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("ATV.jpg"));
				tvStation = 3;
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
		if (stationNumber == 4) {
			try {
				bufferedImage = ImageIO.read(this.getClass().getResource("SAT1.jpg"));
				tvStation = 4;
			} catch (IOException e) {
				System.err.println("Failed to get the image");
			}
		}
		
        wImage = bufferedImage.getWidth();
        hImage = bufferedImage.getHeight();
        int[] size = new int[wImage*hImage];
		pixels = bufferedImage.getRGB(0, 0, wImage, hImage, size, 0,wImage);
	}
}